package android.slc.popup.fast;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.slc.popup.R;
import android.slc.popup.SlcPopup2;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;

import androidx.annotation.AnimRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

public class ShadowPopupWindow {
    //nei bu can shu
    private final Context mContext;
    private FrameLayout mRootView;
    private FrameLayout mContentParentView;
    private boolean mIsEnsureContentParentGravity;
    protected int mDirection;
    private int enterAnimId;
    private int exitAnimId;
    //wai bu can shu
    private int mDuration = -1;
    private int mPositiveAnimRes = R.style.Animation_AppCompat_Dialog_SlcPopupShadow;
    private int mNegativeAnimRes = R.style.Animation_AppCompat_Dialog_SlcPopupShadow_Negative;
    protected Drawable mBgDrawable;
    private boolean mCancelable;
    private OnContentViewInitListener mOnContentViewInitListener;
    private OnShowListener mOnShowListener;
    private OnDismissListener mOnDismissListener;

    public ShadowPopupWindow(@NonNull Context context) {
        super();
        this.mContext = context;
        init();
    }

    private void init() {
        mRootView = new FrameLayout(mContext);
        mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        mContentParentView = new FrameLayout(mContext);
        mContentParentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        mRootView.addView(mContentParentView);
    }

    public ShadowPopupWindow getLightDuration(int duration) {
        this.mDuration = duration;
        return this;
    }

    public ShadowPopupWindow setPositiveAnimRes(@AnimRes int animRes) {
        this.mPositiveAnimRes = animRes;
        return this;
    }

    public ShadowPopupWindow setNegativeAnimRes(@AnimRes int animRes) {
        this.mNegativeAnimRes = animRes;
        return this;
    }

    public ShadowPopupWindow setBgDrawable(Drawable drawable) {
        this.mBgDrawable = drawable;
        return this;
    }

    public ShadowPopupWindow setBgDrawable(int drawableRes) {
        return setBgDrawable(ContextCompat.getDrawable(mContext, drawableRes));
    }

    public ShadowPopupWindow setCancelable(boolean cancelable) {
        this.mCancelable = cancelable;
        return this;
    }

    public ShadowPopupWindow setContentViewInitListener(OnContentViewInitListener onContentViewInitListener) {
        this.mOnContentViewInitListener = onContentViewInitListener;
        return this;
    }

    public ShadowPopupWindow setOnShowListener(OnShowListener mOnShowListener) {
        this.mOnShowListener = mOnShowListener;
        return this;
    }

    public ShadowPopupWindow setOnDismissListener(OnDismissListener onDismissListener) {
        this.mOnDismissListener = onDismissListener;
        return this;
    }


    public ShadowPopupWindow setContentView(@LayoutRes int contentLayout) {
        return setContentView(LayoutInflater.from(this.mContext).inflate(contentLayout, null));
    }

    public ShadowPopupWindow setContentView(@NonNull View contentView) {
        this.mContentParentView.removeAllViews();
        this.mContentParentView.addView(contentView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        ensureContentViewGravity();
        return this;
    }

    public ShadowPopupWindow setAnchor(@NonNull View anchor) {
        int anchorHeight = anchor.getHeight();
        int[] anchorLocation = new int[2];
        anchor.getLocationOnScreen(anchorLocation);
        int heightPixels = SlcPopup2.getScreenHeight(this.mContext);
        FrameLayout.LayoutParams contentParentViewLayoutParams =
                (FrameLayout.LayoutParams) this.mContentParentView.getLayoutParams();
        if (anchorLocation[1] + anchorHeight / 2 <= heightPixels / 2) {
            contentParentViewLayoutParams.height = heightPixels - anchorLocation[1] - anchorHeight;
            contentParentViewLayoutParams.gravity = Gravity.BOTTOM;
            this.mDirection = Gravity.BOTTOM;
        } else {
            contentParentViewLayoutParams.height = anchorLocation[1];
            contentParentViewLayoutParams.gravity = Gravity.TOP;
            this.mDirection = Gravity.TOP;
        }
        this.mIsEnsureContentParentGravity = true;
        ensureContentViewGravity();
        return this;
    }

    protected void ensureContentViewGravity() {
        if (this.mContentParentView.getChildCount() != 0 && this.mIsEnsureContentParentGravity) {
            FrameLayout.LayoutParams contentViewLayoutParams =
                    (FrameLayout.LayoutParams) this.mContentParentView.getChildAt(0).getLayoutParams();
            FrameLayout.LayoutParams contentViewParentLayoutParams =
                    (FrameLayout.LayoutParams) this.mContentParentView.getLayoutParams();
            contentViewLayoutParams.gravity = contentViewParentLayoutParams.gravity == Gravity.BOTTOM ? Gravity.TOP :
                    Gravity.BOTTOM;
        }
    }

    public boolean isCancelable() {
        return this.mCancelable;
    }


    public ShadowPopupWindow create() {
        int[] attr = new int[]{android.R.attr.windowEnterAnimation, android.R.attr.windowEnterAnimation};
        TypedArray array = this.mContext.getTheme().obtainStyledAttributes(mDirection == Gravity.BOTTOM ? this.mNegativeAnimRes :
                this.mPositiveAnimRes, attr);
        this.enterAnimId = array.getResourceId(0, this.mDirection == Gravity.BOTTOM ? R.anim.slc_popup_top_shadow_in_def :
                R.anim.slc_popup_bottom_shadow_in_def);
        this.exitAnimId = array.getResourceId(1, this.mDirection == Gravity.BOTTOM ? R.anim.slc_popup_top_shadow_out_def :
                R.anim.slc_popup_bottom_shadow_out_def);
        array.recycle();

        if (this.mBgDrawable != null) {
            this.mContentParentView.getChildAt(0).setBackground(this.mBgDrawable);
        }
        if (this.mOnContentViewInitListener != null) {
            this.mOnContentViewInitListener.onContentViewInit(this.mContentParentView.getChildAt(0));
        }
        this.mRootView.setOnClickListener(l -> {
            dismiss();
        });
        this.mContentParentView.setOnClickListener(l -> {
            if (isCancelable()) {
                dismiss();
            }
        });
        return this;
    }

    public void dismiss() {
        exitAnim(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                ((ViewGroup) ((Activity) ShadowPopupWindow.this.mContext).getWindow().getDecorView()).removeView(ShadowPopupWindow.this.mRootView);
                if (ShadowPopupWindow.this.mOnDismissListener != null) {
                    ShadowPopupWindow.this.mOnDismissListener.onDismiss();
                }
            }
        });
    }

    /**
     * show
     */
    public void show() {
        create();
        ((ViewGroup) ((Activity) this.mContext).getWindow().getDecorView()).addView(this.mRootView);
        enterAnim(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if (ShadowPopupWindow.this.mOnShowListener != null) {
                    ShadowPopupWindow.this.mOnShowListener.onShow();
                }
            }
        });
    }

    private void enterAnim(Animator.AnimatorListener animationListener) {
        Animation viewAnimation = AnimationUtils.loadAnimation(this.mContext, this.enterAnimId);
        this.mContentParentView.getChildAt(0).setAnimation(viewAnimation);
        ValueAnimator valueAnimator = ValueAnimator.ofInt(0x00000000, 0x80000000);
        valueAnimator.setEvaluator(new ArgbEvaluator());
        valueAnimator.setDuration(this.mDuration == -1 ? viewAnimation.getDuration() : this.mDuration);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener((ValueAnimator animation) -> {
            this.mContentParentView.setBackgroundColor((Integer) animation.getAnimatedValue());
        });
        valueAnimator.addListener(animationListener);
        valueAnimator.start();
    }

    private void exitAnim(Animator.AnimatorListener animationListener) {
        Animation viewAnimation = AnimationUtils.loadAnimation(this.mContext, this.exitAnimId);
        this.mContentParentView.getChildAt(0).startAnimation(viewAnimation);
        ValueAnimator valueAnimator = ValueAnimator.ofInt(0x80000000, 0x00000000);
        valueAnimator.setEvaluator(new ArgbEvaluator());
        valueAnimator.setDuration(this.mDuration == -1 ? viewAnimation.getDuration() : this.mDuration);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener((ValueAnimator animation) -> {
            this.mContentParentView.setBackgroundColor((Integer) animation.getAnimatedValue());
        });
        valueAnimator.addListener(animationListener);
        valueAnimator.start();
    }

    public interface OnContentViewInitListener {
        void onContentViewInit(View view);
    }

    public interface OnShowListener {
        void onShow();
    }

    public interface OnDismissListener {
        void onDismiss();
    }
}
